package spring.core.aop.cglib;

import spring.core.aop.TeacherService;
import spring.core.aop.jdkproxy.StudentService;
import spring.core.aop.jdkproxy.StudentServiceImpl;

import java.lang.reflect.Method;

import org.springframework.aop.support.AopUtils;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;

/**
 * @author 1203056
 * @version Id: CglibProxyDemo.java, v 0.1 2021-09-05 23:17 1203056 Exp $
 */
public class CglibProxyDemo {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(StudentServiceImpl.class);
        enhancer.setInterfaces(new Class[] { TeacherService.class });
        enhancer.setCallback(new MethodInterceptor() {
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                if (ReflectionUtils.isToStringMethod(method)) {
                    return proxy.getClass().toString();//method.invoke(target,args);
                } else if (ReflectionUtils.isHashCodeMethod(method)) {
                    return System.identityHashCode(proxy);
                }
                if (method.getDeclaringClass() == StudentServiceImpl.class) {
                    //TODO 与jdkProxy不同
                    System.out.println("before ......");
                    return methodProxy.invokeSuper(proxy, args);//method.invoke(target,args);
                }
                System.out.println("invoke "+method);
                return null;
            }
        });
        Object proxy = enhancer.create(new Class[]{String.class},new Object[]{"w"});
        System.out.println("proxy = "+proxy);

        System.out.println(AopUtils.isCglibProxy(proxy));
        System.out.println(ClassUtils.isCglibProxy(proxy));
        StudentService studentService = (StudentService)proxy ;
        studentService.echo("hello");
        TeacherService teacherService =  (TeacherService)proxy;
        teacherService.teach("hello");
    }
}
